/*
 * Copyright (c) 2024 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

#include "scanner.h"

using namespace dev;

bool Scanner::init(mc::mutable_dict& csr_object, const mc::dict& connector) {
    try {
        from_variant(csr_object, *this);

        // 验证必需字段是否被正确设置
        auto chip_value = i_scanner.Chip.get_value();
        if (chip_value.is_null() || chip_value.as<std::string>().empty()) {
            elog("Scanner init failed: Chip field is null or empty");
            return false;
        }

        auto period_value = i_scanner.Period.get_value();
        if (period_value.is_null() || period_value.as<uint32_t>() == 0) {
            elog("Scanner init failed: Period field is null or zero");
            return false;
        }

        auto offset_value = i_scanner.Offset.get_value();
        if (offset_value.is_null()) {
            elog("Scanner init failed: Offset field is null");
            return false;
        }

        auto size_value = i_scanner.Size.get_value();
        if (size_value.is_null() || size_value.as<uint8_t>() == 0) {
            elog("Scanner init failed: Size field is null or zero");
            return false;
        }

        m_initialized = true;

        // 初始化Scanner信号连接
        i_scanner.init_scanner_signal();

        // 启动Scanner任务
        i_scanner.start_scanner_task();
        return true;
    } catch (const std::exception& e) {
        elog("Scanner init failed, exception: ${exception}", ("exception", e.what()));
        return false;
    }
}

bool Scanner::start() {
    try {
        if (!m_initialized) {
            elog("Scanner start failed: not initialized");
            return false;
        }

        i_scanner.start_scanner_task();
        return true;
    } catch (const std::exception& e) {
        elog("Scanner start failed, exception: ${exception}", ("exception", e.what()));
        return false;
    }
}

bool Scanner::stop() {
    try {
        // 设置ScanEnabled为0，这会触发信号处理逻辑
        i_scanner.ScanEnabled.set_value(0);
        return true;
    } catch (const std::exception& e) {
        elog("Scanner stop failed, exception: ${exception}", ("exception", e.what()));
        return false;
    }
}

bool Scanner::set_value(uint64_t value) {
    try {
        i_scanner.Value.set_value(value);
        ilog("Scanner set value to ${value}", ("value", value));
        return true;
    } catch (const std::exception& e) {
        elog("Scanner set_value failed, exception: ${exception}", ("exception", e.what()));
        return false;
    }
}

// 自定义反序列化：扁平结构映射到 i_scanner
void dev::Scanner::from_variant(const mc::dict& d, dev::Scanner& obj) {
    mc::from_variant(d, obj.i_scanner);
}

MC_REFLECT(dev::Scanner, ((i_scanner, "bmc.dev.Scanner")))